package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.exception.StgyException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.web.admin.dto.AgreementInfoSearchDto;
import com.atguigu.lease.web.admin.mapper.LeaseAgreementMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.AgreementDetailsVo;
import com.atguigu.lease.web.admin.vo.AgreementInfoVo;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author 1
* @description 针对表【lease_agreement(租约信息表)】的数据库操作Service实现
* @createDate 2024-08-28 11:00:26
*/
@Service
public class LeaseAgreementServiceImpl extends ServiceImpl<LeaseAgreementMapper, LeaseAgreement>
    implements LeaseAgreementService {
    @Resource
    PaymentTypeService paymentTypeService;
    @Resource
    LeaseTermService leaseTermService;
    @Resource
    RoomInfoService roomInfoService;
    @Resource
    ApartmentInfoService apartmentInfoService;
    @Override
    public Page<AgreementInfoVo> pageItem(AgreementInfoSearchDto searchDto) {
        //1、先查询LeaseAgreement
        //2、再查询公寓详情
        //3、查询房间详情
        //    检索条件需要从上面三张表中获取
        Page<AgreementInfoVo> page = searchDto.getPage(AgreementInfoVo.class);
        List<AgreementInfoVo> agreementInfoVos =  baseMapper
                .selectAgreementInfoVoPage(page , searchDto).stream().map(agreementInfoVo -> {
                    //查询他需要的其他数据绑定
                    //4、查询支付方式paymentTypeId
                    agreementInfoVo.setPaymentType(paymentTypeService
                                    .getById(agreementInfoVo.getPaymentTypeId()));
                    //5、查询租期
                    agreementInfoVo.setLeaseTerm(leaseTermService
                            .getById(agreementInfoVo.getLeaseTermId()));

                    return agreementInfoVo;
                }).collect(Collectors.toList());


        page.setRecords(agreementInfoVos);
        return page;
    }

    @Override
    public AgreementDetailsVo getDetailsById(Long id) {
        LeaseAgreement leaseAgreement = this.getById(id);
        if(ObjectUtils.isEmpty(leaseAgreement)){
            throw new StgyException(ResultCodeEnum.DATA_ERROR);
        }

        LeaseTerm leaseTerm = leaseTermService.getById(leaseAgreement.getLeaseTermId());
        PaymentType paymentType = paymentTypeService.getById(leaseAgreement.getPaymentTypeId());
        ApartmentInfo apartmentInfo = apartmentInfoService.getById(leaseAgreement.getApartmentId());
        RoomInfo roomInfo = roomInfoService.getById(leaseAgreement.getRoomId());
        //组装租约详情数据：
        AgreementDetailsVo agreementDetailsVo = new AgreementDetailsVo();
        BeanUtils.copyProperties(leaseAgreement , agreementDetailsVo);
        agreementDetailsVo.setLeaseTerm(leaseTerm);
        agreementDetailsVo.setPaymentType(paymentType);
        agreementDetailsVo.setApartmentInfo(apartmentInfo);
        agreementDetailsVo.setRoomInfo(roomInfo);

        return agreementDetailsVo;
    }

    @Override
    public boolean saveOrUpdateAgreement(LeaseAgreement leaseAgreement) {
        //业务判断： 指定房间是否已存在租约，否则不能租
        long id = leaseAgreement.getId()==null?-1L:leaseAgreement.getId();
        //查询本次要更新的租约信息
        LeaseAgreement dbLeaseAgreement = this.getOne(Wrappers.lambdaQuery(LeaseAgreement.class)
                .eq(LeaseAgreement::getApartmentId, leaseAgreement.getApartmentId())
                .eq(LeaseAgreement::getRoomId, leaseAgreement.getRoomId())
                // 3 4 6状态表示房间状态为可租
                //更新时： 如果房间存在租约 并且是自己的租约
//                .in(LeaseAgreement::getStatus, 3, 4, 6)
                .last("limit 1"));
        // 如果新增：查询不到租约信息  或者 查询到的租约信息 状态是3, 4, 6，可以新增
        List<Integer> statusList = Arrays.asList(3, 4, 6);
        // 如果更新：查询不到租约信息  或者 查询到租约信息id等于自己的，可以更新  或者查询到租约信息的id不等于自己的，但是状态为3, 4, 6 可以更新
        if(dbLeaseAgreement==null  || statusList.contains(dbLeaseAgreement.getStatus()) ||
                (!statusList.contains(dbLeaseAgreement.getStatus()) && id == dbLeaseAgreement.getId())  ){
            return this.saveOrUpdate(leaseAgreement);
        }
        /*
            如果 更新了房间id 102
                - 房间没有租约信息
                        查询数据库中的租约信息为空
                - 房价有租约信息
                        查询到的租约状态为3，4，6 可以更新
                - 房价有租约信息
                        无论租约状态是什么，只要租约的id等于 提交请求的租约id 也可以更新
         */

        throw new StgyException(ResultCodeEnum.DATA_ERROR);
    }
    /*
        定时检查租约状态:
            更新或删除租约状态
     */
    @Override
    public void checkAgreementStatus() {
        //1、查询所有的租约
        List<LeaseAgreement> agreements = this.list();
        //2、遍历租约
        /*
             1、如果租约状态为 1
                需要检查租约最后一次更新的时间 和现在相差的时间 如果超过允许的时间 修改为取消3
             2、如果租约的状态为7
                需要检查租约到期时间 和现在的时间差  如果超过允许的值   修改为 退租6
             3、如果租约的状态为2
                检查租约的到期时间 大于等于当前的时间 修改状态为7
             4、如果租约状态为6
                检查租约的到期时间  超过允许的时间  逻辑删除
         */
        // 状态为1的租约列表
        DateTime now = new DateTime().withTimeAtStartOfDay();
        agreements.stream()
                .filter(leaseAgreement ->
                    leaseAgreement.getStatus().equals(1))
                .forEach(leaseAgreement -> {
                    //如果待签约的时间超过3天 修改为取消状态
                    DateTime dateTime = new DateTime(leaseAgreement.getUpdateTime()).plusDays(4).withTimeAtStartOfDay();
                    //获取当前时间的 时间毫秒数
                    if(dateTime.isBefore(now)){
                        //修改租约的状态为取消状态 3
                        this.update(Wrappers.lambdaUpdate(LeaseAgreement.class)
                                .eq(LeaseAgreement::getId , leaseAgreement.getId())
                                .eq(LeaseAgreement::getStatus , 1)
                                .set(LeaseAgreement::getStatus , 3)
                                .set(LeaseAgreement::getUpdateTime , new Date()));
                    }

                });

        agreements.stream()
                .filter(leaseAgreement ->
                        leaseAgreement.getStatus().equals(2))
                .forEach(leaseAgreement -> {
                    //已签约的，如果租期到期 更新为 7 等待用户续约
                    DateTime dateTime = new DateTime(leaseAgreement.getLeaseEndDate());
                    //获取当前时间的 时间毫秒数
                    if(dateTime.equals(now) || dateTime.isBefore(now)){
                        //修改租约的状态为等待续约状态7
                        this.update(Wrappers.lambdaUpdate(LeaseAgreement.class)
                                .eq(LeaseAgreement::getId , leaseAgreement.getId())
                                .eq(LeaseAgreement::getStatus , 2)
                                .set(LeaseAgreement::getStatus , 7)
                                .set(LeaseAgreement::getUpdateTime , new Date()));
                    }
                });
        agreements.stream()
                .filter(leaseAgreement ->
                        leaseAgreement.getStatus().equals(7))
                .forEach(leaseAgreement -> {
                    //租期到期等待续约的租期  超过3天 更新为6已退租
                    DateTime dateTime = new DateTime(leaseAgreement.getLeaseEndDate()).plusDays(4);
                    //获取当前时间的 时间毫秒数
                    if(dateTime.isBefore(now)){
                        //修改租约的状态为等待续约状态7
                        this.update(Wrappers.lambdaUpdate(LeaseAgreement.class)
                                .eq(LeaseAgreement::getId , leaseAgreement.getId())
                                .eq(LeaseAgreement::getStatus , 7)
                                .set(LeaseAgreement::getStatus , 6)
                                .set(LeaseAgreement::getUpdateTime , new Date()));
                    }
                });

        agreements.stream()
                .filter(leaseAgreement ->
                        leaseAgreement.getStatus().equals(6))
                .forEach(leaseAgreement -> {
                    //租期到期等待续约的租期  超过3天 更新为6已退租
                    DateTime dateTime = new DateTime(leaseAgreement.getLeaseEndDate()).plusDays(7);
                    //获取当前时间的 时间毫秒数
                    if(dateTime.isAfter(now)){
                        this.removeById(leaseAgreement.getId());
                        //修改租约的状态为等待续约状态7
                    }
                    //获取时间日期的毫秒数 相减
                });
    }
}




